package com.ruoyi.system.support;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * HTTP工具类
 * 提供HTTP POST请求的封装方法，主要用于短信API调用
 * 
 * @author ruoyi
 */
public class HttpUtils {

    /**
     * 发送HTTP POST请求
     * 
     * @param host 主机地址，如 https://api.example.com
     * @param path API路径，如 /sms/send
     * @param method HTTP方法，通常为POST
     * @param headers 请求头信息，包含鉴权信息等
     * @param querys URL查询参数
     * @param bodys 请求体参数（表单格式）
     * @return HTTP响应对象
     * @throws Exception 请求异常
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      Map<String, String> bodys) throws Exception {
        // 创建默认的HTTP客户端
        CloseableHttpClient httpClient = HttpClients.createDefault();
        
        // 构建完整的请求URL（包含查询参数）
        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        
        // 设置请求头信息
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        
        // 如果有请求体参数，则构建表单实体
        if (bodys != null) {
            List<NameValuePair> params = new ArrayList<>();
            // 将Map参数转换为NameValuePair列表
            for (String key : bodys.keySet()) {
                params.add(new BasicNameValuePair(key, bodys.get(key)));
            }
            // 创建表单编码实体，使用UTF-8编码
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, "utf-8");
            // 设置内容类型为表单格式
            formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
            request.setEntity(formEntity);
        }
        
        // 执行请求并返回响应
        return httpClient.execute(request);
    }

    /**
     * 构建完整的URL地址
     * 将主机、路径和查询参数拼接成完整的URL
     * 
     * @param host 主机地址
     * @param path API路径
     * @param querys 查询参数Map
     * @return 完整的URL地址
     * @throws UnsupportedEncodingException URL编码异常
     */
    private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
        StringBuilder sbUrl = new StringBuilder();
        // 添加主机地址
        sbUrl.append(host);
        
        // 处理主机和路径之间的斜杠问题
        if (!host.endsWith("/") && !path.startsWith("/")) {
            sbUrl.append("/"); // 如果主机不以/结尾且路径不以/开始，则添加/
        }
        sbUrl.append(path);
        
        // 处理查询参数
        if (null != querys) {
            StringBuilder sbQuery = new StringBuilder();
            // 遍历所有查询参数
            for (Map.Entry<String, String> query : querys.entrySet()) {
                // 如果不是第一个参数，则添加&分隔符
                if (0 < sbQuery.length()) {
                    sbQuery.append("&");
                }
                // 检查参数名是否有效
                if (query.getKey() != null && query.getKey().length() > 0) {
                    sbQuery.append(query.getKey());
                    // 检查参数值是否有效
                    if (query.getValue() != null && query.getValue().length() > 0) {
                        sbQuery.append("=");
                        // 对参数值进行URL编码，防止特殊字符影响URL解析
                        sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
                    }
                }
            }
            // 如果有查询参数，则添加到URL中
            if (0 < sbQuery.length()) {
                sbUrl.append("?").append(sbQuery);
            }
        }
        return sbUrl.toString();
    }
}


